# Copyright (c) 2020 Presto Labs Pte. Ltd.
# Author: linchuan

import requests
import datetime
import calendar
from coin2.exchange.product_info import ProductInfoDefault
from coin2.exchange.symbology import SymbologyInfo


def get_last_friday(year, month):
  cal = calendar.Calendar(4)  # Make Friday the first day.
  week_list = cal.monthdayscalendar(year, month)
  fridays = [week[0] for week in week_list if week[0] != 0]
  return datetime.datetime(year, month, fridays[-1])


def get_expiries(ts):
  expire_time = 24 * 3600  # or 3 * 3600 ??? what is the exact expiration time?
  dt = datetime.datetime.utcfromtimestamp(ts / 1e9)
  expire_dates = [
      get_last_friday(dt.year, 3),
      get_last_friday(dt.year, 6),
      get_last_friday(dt.year, 9),
      get_last_friday(dt.year, 12),
      get_last_friday(dt.year + 1, 3),
      get_last_friday(dt.year + 1, 6),
      get_last_friday(dt.year + 1, 9),
  ]

  for idx, expire_dt in enumerate(expire_dates):
    if ts < int((expire_dt.timestamp() + expire_time) * 1e9):
      return expire_dates[idx], expire_dates[idx + 1], expire_dates[idx + 2]

  raise Exception()


def calc_symbol_groups(base, native_base, ts):
  e1, e2, e3 = get_expiries(ts)
  symbol1 = {
              'symbol': base + '-USD.QUARTER',
              'native_symbol': native_base + '-' + e1.strftime('%m%d')
            }
  symbol2 = {
              'symbol': base + '-USD.NEXT_QUARTER',
              'native_symbol': native_base + '-' + e2.strftime('%m%d')
            }
  symbol3 = {
              'symbol': base + '-USD.NNEXT_QUARTER',
              'native_symbol': native_base + '-' + e3.strftime('%m%d')
            }
  return [symbol1, symbol2, symbol3]


def generate():
  mea = 'Futures.Ftx.v1'
  me = 'Futures.Ftx'
  default = ProductInfoDefault()
  symbol_info = SymbologyInfo()
  data = requests.get('https://ftx.com/api/markets').json()['result']

  pis = []
  bases = []
  for info in data:
    str_list = info['name'].split('-')
    if len(str_list) != 2:
      continue

    # tokenized stocks futures exipry date is different with common futures
    if 'tokenizedEquity' in info:
      if info['tokenizedEquity']:
        continue

    is_quarter = False
    if info['name'].endswith('-PERP'):
      expiry = 'PERPETUAL'
    elif str_list[1].isdigit():
      is_quarter = True
    else:
      continue

    native_symbol = info['name']
    native_base = info['underlying']
    native_quote = 'USD'
    base = symbol_info.native_to_norm_currency(mea, native_base)
    quote = symbol_info.native_to_norm_currency(mea, native_quote)
    symbol = "%s-%s.%s" % (base, quote, expiry)

    itmes = [{"symbol": symbol, "native_symbol": native_symbol}]
    if (is_quarter):
      if(base not in bases):
       itmes = calc_symbol_groups(base, native_base, default.fetched_time)
       bases.append(base)
      else:
        continue

    for itme in itmes:
      pi = dict(
          symbol=itme["symbol"],
          base=base,
          quote=quote,
          native_symbol=itme["native_symbol"],
          native_base=native_base,
          native_quote=native_quote,
          price_ticksize=float(info['priceIncrement']),
          qty_ticksize=float(info['sizeIncrement']),
          contract_value=1,
      )
      pi = {**pi, **default.product_info(me, symbol)}
      pis.append(pi)

  pis = sorted(pis, key=lambda x: x['symbol'])
  return pis


def gen_coin1_constants():
  data = generate()
  data = convert_coin1_constants(data)
  return data


def convert_coin1_constants(data):
  symbol_list = [info['native_symbol'] for info in data]
  quote_currency_list = [info['native_quote'] for info in data]
  base_currency_list = [info['native_base'] for info in data]
  currency_list = base_currency_list + quote_currency_list
  res = {
      'symbol_list': list(set(symbol_list)),
      'base_currency_list': list(set(base_currency_list)),
      'quote_currency_list': list(set(quote_currency_list)),
      'currency_list': list(set(currency_list)),
  }
  return res


if __name__ == "__main__":
  import json
  print(json.dumps(generate(), indent=2))
